package com.shuaiche.yeguan.util;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;
import android.util.Base64;


import com.google.gson.Gson;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * 1、SharedPreferences操作工具类,以私有的文件类型保存数据,文件名以字段SP_NAME值为准，可自行修改。
 * 2、添加对Java对象存储和获取的方法，且该对象必须实现序列化接口。
 * 3、添加对Java bean对象的存储和获取方法。
 */
public class SPUtils {
	
	/**
	 * SharedPreferences存储的文件名.
	 */
	private final static String SP_NAME = "sc_config";

	public final static String USER_INFO = "USER_INFO";
	public final static String COMPANY_INFO = "COMPANY_INFO";
	public final static String IS_AGREE = "IS_AGREE";
	public final static String LAST_PHONE = "LAST_PHONE";//上次登录的号码
	public final static String API_TYPE = "API_TYPE";//环境 0和1是开发 2测试 3正式


	/**
	 * SharedPreferences.
	 */
	private static SharedPreferences sp;

	public static SharedPreferences getSP(Context context){
		sp = context.getApplicationContext().getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
		return sp;
	}

	public static void remove(Context context, String key){
		if (sp == null){
			getSP(context);
		}
		sp.edit().remove(key).commit();
	}

	/**
	 * 向SharedPreferences中保存布尔类型数据.
	 * @param context  上下文
	 * @param key       键
	 * @param value     值
	 */
	public static void saveBoolean(Context context, String key, boolean value) {
		if (sp == null){
			getSP(context);
		}
		sp.edit().putBoolean(key, value).commit();
	}

	/**
	 * 保存字符串
	 * @param context
	 * @param key
	 * @param value
	 */
	public static void saveString(Context context, String key, String value) {
		if (sp == null){
			getSP(context);
		}
		sp.edit().putString(key, value).commit();
		
	}
	
	/**
	 * 清空SharedPreferences中所有的数据.
	 * @param context  上下文
	 */
	public static void clear(Context context){
		if (sp == null){
			getSP(context);
		}
		sp.edit().clear().commit();
	}

	
	/**
	 * 保存long型
	 * @param context
	 * @param key
	 * @param value
	 */
	public static void saveLong(Context context, String key, long value) {
		if (sp == null){
			getSP(context);
		}
		sp.edit().putLong(key, value).commit();
	}

	
	/**
	 * 保存int型
	 * @param context
	 * @param key
	 * @param value
	 */
	public static void saveInt(Context context, String key, int value) {
		if (sp == null){
			getSP(context);
		}
		sp.edit().putInt(key, value).commit();
	}

	
	/**
	 * 保存float型
	 * @param context
	 * @param key
	 * @param value
	 */
	public static void saveFloat(Context context, String key, float value) {
		if (sp == null){
			getSP(context);
		}
		sp.edit().putFloat(key, value).commit();
	}

	
	/**
	 * 获取字符串
	 * @param context  上下文
	 * @param key       键
	 * @param defValue  默认值,如果在SharedPreferences中,键没有对应的值,就返回该默认值.
	 * @return   返回SharedPreferences中,给定键对应的值,如果没有就返回传入的默认值.
	 */
	public static String getString(Context context, String key, String defValue) {
		if (sp == null){
			getSP(context);
		}
		return sp.getString(key, defValue);
	}

	
	/**
	 * 获取int值
	 * @param context
	 * @param key
	 * @param defValue
	 * @return
	 */
	public static int getInt(Context context, String key, int defValue) {
		if (sp == null){
			getSP(context);
		}
		return sp.getInt(key, defValue);
	}

	
	/**
	 * 获取long值
	 * @param context
	 * @param key
	 * @param defValue
	 * @return
	 */
	public static long getLong(Context context, String key, long defValue) {
		if (sp == null){
			getSP(context);
		}
		return sp.getLong(key, defValue);
	}

	
	/**
	 * 获取float值
	 * @param context
	 * @param key
	 * @param defValue
	 * @return
	 */
	public static float getFloat(Context context, String key, float defValue) {
		if (sp == null){
			getSP(context);
		}
		return sp.getFloat(key, defValue);
	}

	
	/**
	 * 获取布尔值
	 * @param context
	 * @param key
	 * @param defValue
	 * @return
	 */
	public static boolean getBoolean(Context context, String key,
                                     boolean defValue) {
		if (sp == null){
			getSP(context);
		}
		return sp.getBoolean(key, defValue);
	}


	/**
	 * 保存Java Bean对象。
	 * @param context
	 * @param key
	 * @param obj
     */
	public static  void  saveBean(Context context, String key, Object obj){

		Gson gson=new Gson();
		String json=gson.toJson(obj);
		saveString(context,key,json);
	}


	/**
	 * 获取Java Bean 对象。
	 * @param context
	 * @param key
	 * @param t
	 * @param <T>
     * @return
     */
	public static <T> T getBean(Context context, String key, Class<T> t){
		String cache=getString(context,key,"");
		if(!TextUtils.isEmpty(cache)){
			Gson gson=new Gson();
			return gson.fromJson(cache,t);
		}else {
			return null;
		}
	}


	
	/**
	 * 将对象进行base64编码后保存到SharedPreferences中。
	 * @param context  上下文
	 * @param key       键
	 * @param object    对象
	 */
	public static void saveObj(Context context, String key, Serializable object) {
		if (sp == null){
			getSP(context);
		}
		
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(baos);
			oos.writeObject(object);
			// 将对象的转为base64码
			String objBase64 = new String(Base64.encode(baos.toByteArray(), Base64.NO_WRAP));
			sp.edit().putString(key,objBase64).commit();
			oos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	
	/**
	 * 将SharePref中经过base64编码的对象读取出来
	 * @param context
	 * @param key
	 * @return
	 */
	public static Object getObj(Context context, String key) {
		if (sp == null){
			getSP(context);
		}
		String objBase64 = sp.getString(key, null);
		if (TextUtils.isEmpty(objBase64))
			return null;

		// 对Base64格式的字符串进行解码
		byte[] base64Bytes = Base64.decode(objBase64.getBytes(), Base64.NO_WRAP);
		ByteArrayInputStream bais = new ByteArrayInputStream(base64Bytes);

		ObjectInputStream ois;
		Object obj = null;
		try {
			ois = new ObjectInputStream(bais);
			obj = (Object) ois.readObject();
			ois.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}

	/**
	 * 根据key获取config.properties里面的值
	 * @param context
	 * @param key
	 * @return
	 */
	public static String getProperty(Context context, String key) {
		try {
			Properties props = new Properties();
			InputStream input = context.getAssets().open("config.properties");
			if (input != null) {
				props.load(input);
				return props.getProperty(key);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 存储List集合
	 * @param context 上下文
	 * @param key 存储的键
	 * @param list 存储的集合
	 */
	public static void putList(Context context, String key, List<? extends Serializable> list) {
		try {
			put(context, key, list);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取List集合
	 * @param context 上下文
	 * @param key 键
	 * @param <E> 指定泛型
	 * @return List集合
	 */
	public static <E extends Serializable> List<E> getList(Context context, String key) {
		try {
			return (List<E>) get(context, key);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 存储Map集合
	 * @param context 上下文
	 * @param key 键
	 * @param map 存储的集合
	 * @param <K> 指定Map的键
	 * @param <V> 指定Map的值
	 */
	public static <K extends Serializable, V extends Serializable> void putMap(Context context,
                                                                               String key, Map<K, V> map)
	{
		try {
			put(context, key, map);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static <K extends Serializable, V extends Serializable> Map<K, V> getMap(Context context,
                                                                                    String key)
	{
		try {
			return (Map<K, V>) get(context, key);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**存储对象*/
	private static void put(Context context, String key, Object obj)
			throws IOException
	{
		if (obj == null) {//判断对象是否为空
			return;
		}
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos  = null;
		oos = new ObjectOutputStream(baos);
		oos.writeObject(obj);
		// 将对象放到OutputStream中
		// 将对象转换成byte数组，并将其进行base64编码
		String objectStr = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));
		baos.close();
		oos.close();

		putString(context, key, objectStr);
	}

	/**获取对象*/
	private static Object get(Context context, String key)
			throws IOException, ClassNotFoundException
	{
		String wordBase64 = getString(context, key);
		// 将base64格式字符串还原成byte数组
		if (TextUtils.isEmpty(wordBase64)) { //不可少，否则在下面会报java.io.StreamCorruptedException
			return null;
		}
		byte[]               objBytes = Base64.decode(wordBase64.getBytes(), Base64.DEFAULT);
		ByteArrayInputStream bais     = new ByteArrayInputStream(objBytes);
		ObjectInputStream ois      = new ObjectInputStream(bais);
		// 将byte数组转换成product对象
		Object obj = ois.readObject();
		bais.close();
		ois.close();
		return obj;
	}

	/**
	 * 存入字符串
	 *
	 * @param context 上下文
	 * @param key     字符串的键
	 * @param value   字符串的值
	 */
	public static void putString(Context context, String key, String value) {
		SharedPreferences preferences = getSP(context);
		//存入数据
		SharedPreferences.Editor editor = preferences.edit();
		editor.putString(key, value);
		editor.commit();
	}

	/**
	 * 获取字符串
	 *
	 * @param context 上下文
	 * @param key     字符串的键
	 * @return 得到的字符串
	 */
	public static String getString(Context context, String key) {
		SharedPreferences preferences = getSP(context);
		return preferences.getString(key, "");
	}


	public static void setfunctions(Activity activity, String functionTitle){
		try {
			List<Serializable> functionList = getList(activity, "functionList");
			if (functionList!=null && functionList.size()>0){
				for (int i=0;i<functionList.size();i++){
					if (functionTitle.equals(functionList.get(i))){
						functionList.remove(i);
						break;
					}
				}
			}

			if (functionList!=null && functionList.size()>=5){
				functionList.remove(4);
			}
			if (functionList ==null){
				functionList = new ArrayList<>();
			}
			functionList.add(0,functionTitle);
			putList(activity,"functionList",functionList);
		}catch (Exception e){

		}
	}

}
